home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / editor / j414src.arc / JOVE.C < prev    next >
C/C++ Source or Header  |  1989-10-10  |  29KB  |  1,440 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. /* Contains the main loop initializations, and some system dependent
  9.    type things, e.g. putting terminal in CBREAK mode, etc. */
  10.  
  11. #include "jove.h"
  12. #include "fp.h"
  13. #include "termcap.h"
  14. #include "ctype.h"
  15. #include "chars.h"
  16. #include "disp.h"
  17. #include "re.h"    /* for find_tag() */
  18. #include "rec.h"
  19. #if defined(IPROCS)
  20. # include "iproc.h"
  21. #endif
  22.  
  23. #ifdef MAC
  24. # include "mac.h"
  25. #else
  26. # ifdef    STDARGS
  27. #  include <stdarg.h>
  28. # else
  29. #  include <varargs.h>
  30. # endif
  31. # include <sys/stat.h>
  32. #endif
  33.  
  34. #include <signal.h>
  35. #include <errno.h>
  36.  
  37. #ifdef UNIX
  38. # ifndef SYSV
  39. #  include <sgtty.h>
  40. # else
  41. #  include <termio.h>
  42. # endif /* SYSV */
  43. #endif /* UNIX */
  44.  
  45. #ifdef MSDOS
  46. # include <process.h>
  47. #endif /* MSDOS */
  48.  
  49. #ifndef MAC
  50. # include <fcntl.h>
  51. #endif
  52.  
  53. #ifdef MSDOS
  54. extern    time_t    time proto((time_t *));
  55. private    void    break_off proto((void)),
  56.         break_rst proto((void));
  57. #endif
  58.  
  59. private void
  60.     DoKeys proto((int firsttime)),
  61.     UNIX_cmdline proto((int argc,char * *argv));
  62.  
  63. #ifdef MSDOS
  64. extern void UnsetTerm proto((char *));
  65. #else
  66. private void UnsetTerm proto((char *));
  67. #endif
  68.  
  69. /* Various tty state structures.
  70.  * Each is an array, subscripted by one of "OFF" or "ON".
  71.  */
  72.  
  73. #ifndef MAC
  74. #include "ttystate.h"
  75. #endif
  76.  
  77. #ifdef UNIX
  78. # ifdef TIOCSLTC
  79. struct ltchars    ls[2];
  80. # endif /* TIOCSLTC */
  81.  
  82. # if defined(TIOCGETC) && !defined(SYSV)
  83. struct tchars    tc[2];
  84. # endif
  85.  
  86. # ifdef PASS8            /* use pass8 instead of raw for meta-key */
  87. private int    lmword[2];        /* local mode word */
  88. # endif
  89.  
  90. # ifdef BRLUNIX
  91. struct sg_brl    sg[2];
  92. # else
  93. #  ifdef SYSV
  94. struct termio    sg[2];
  95. #  else /* SYSV */
  96. struct sgttyb    sg[2];
  97. #  endif /* SYSV */
  98. # endif /* BRLUNIX */
  99.  
  100. # ifdef BIFF
  101. private struct stat    tt_stat;    /* for biff */
  102. #  ifndef BSD4_2
  103. private char    *tt_name = 0;        /* name of the control tty */
  104. extern char    *ttyname();        /* for systems w/o fchmod ... */
  105. #  endif
  106. private int    dw_biff = NO;        /* whether or not to fotz at all */
  107. # endif /* BIFF */
  108. #endif /* UNIX */
  109.  
  110. int    errormsg;
  111. char    NullStr[] = "";
  112. jmp_buf    mainjmp;
  113.  
  114.  
  115. #ifdef MSDOS
  116. # define SIGHUP    99
  117. #endif /* MSDOS */
  118.  
  119. /* finish() does not return, so it is funny that it returns a non-void
  120.  * result.  This is because most systems claim that signal(2) deals
  121.  * with functions of type int ().  ANSI changes this: the function
  122.  * type must be void (int).  This bridge must soon be crossed.
  123.  */
  124. SIGRESULT
  125. finish(code)
  126. int    code;
  127. {
  128.     int    CoreDump = (code != 0 && code != SIGHUP),
  129.         DelTmps = 1;        /* Usually we delete them. */
  130.  
  131.     if (code == SIGINT) {
  132.         char    c;
  133. #if defined(IPROCS) && defined(PIPEPROCS)
  134.         int    started;
  135. #endif
  136. #ifndef MENLO_JCL
  137.         (void) signal(code, finish);
  138. #endif
  139.         f_mess("Abort (Type 'n' if you're not sure)? ");
  140. #ifndef MSDOS
  141. # if defined(IPROCS) && defined(PIPEPROCS)
  142.         started = kbd_stop();
  143. # endif
  144. #ifdef SYSV
  145.         if (read(0, &c, (size_t) 1) != 1)
  146. #endif
  147.             (void) read(0, &c, (size_t) 1);
  148. # if defined(IPROCS) && defined(PIPEPROCS)
  149.         if (started)
  150.             (void) kbd_strt();
  151. # endif
  152. #else /* MSDOS */
  153.         c = getrawinchar();
  154. #endif /* MSDOS */
  155.         message(NullStr);
  156.         if ((c & 0377) != 'y') {
  157.             redisplay();
  158.             SIGRETURN;
  159.         }
  160.     }
  161.     DisabledRedisplay = YES;
  162. #ifndef MAC
  163.     UnsetTerm(NullStr);
  164. #endif
  165. #if defined(IPROCS) && defined(PIPEPROCS)
  166.     kbd_kill();        /* kill the keyboard process */
  167. #endif
  168. #ifndef MSDOS
  169.     if (code != 0) {
  170.         if (!Crashing) {
  171.             Crashing = YES;
  172.             lsave();
  173.             SyncRec();
  174.             writef("JOVE CRASH!! (code %d)\n", code);
  175.             if (ModBufs(1)) {
  176.                 writef("Your buffers have been saved.\n");
  177.                 writef("Use \"jove -r\" to have a look at them.\n");
  178.                 DelTmps = 0;    /* Don't delete anymore. */
  179.             } else
  180.                 writef("You didn't lose any work.\n");
  181.         } else
  182.             writef("\r\nYou may have lost your work!\n");
  183.     }
  184. #endif /* MSDOS */
  185.     flusho();
  186.     if (DelTmps) {
  187. #if defined(IPROCS) && !defined(PIPEPROCS)
  188.         (void) signal(SIGCHLD, SIG_IGN);
  189. #endif
  190.         tmpclose();
  191. #ifndef MSDOS
  192.         recclose();
  193. #endif /* MSDOS */
  194.     }
  195. #ifdef UNIX
  196.     if (CoreDump)
  197.         abort();
  198. #ifdef PROFILING
  199.     exit(0);
  200. #else
  201.     _exit(0);
  202. #endif
  203. #else /* MSDOS or MAC*/
  204. #ifdef MSDOS
  205.     break_rst();    /* restore previous ctrl-c handling */
  206. #endif
  207.     exit(0);
  208. #endif /* UNIX */
  209.     /*NOTREACHED*/
  210. }
  211.  
  212. private char    smbuf[20],
  213.         *bp = smbuf;
  214. private int    nchars = 0;
  215.  
  216. private char    peekbuf[10],
  217.         *peekp = peekbuf;
  218.  
  219. #if defined(SYSV) || defined(M_XENIX)
  220. void
  221. setblock(fd, on)    /* turn blocking on or off */
  222. register int    fd, on;
  223. {
  224.     static int blockf, nonblockf;
  225.     static int first = 1;
  226.     int flags;
  227.  
  228.     if (first) {
  229.     first = 0;
  230.     if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
  231.         finish(SIGHUP);
  232.     blockf = flags & ~O_NDELAY;    /* make sure O_NDELAY is off */
  233.     nonblockf = flags | O_NDELAY;    /* make sure O_NDELAY is on */
  234.     }
  235.     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
  236.     finish(SIGHUP);
  237. }
  238. #endif /* SYSV */
  239.  
  240. private int
  241. Peekc()
  242. {
  243.     int    c;
  244.  
  245.     if (peekp == peekbuf)
  246.         c = EOF;
  247.     else
  248.         c = *--peekp & 0377;
  249.     return c;
  250. }
  251.  
  252. void
  253. Ungetc(c)
  254. int    c;
  255. {
  256.     if (peekp == &peekbuf[(sizeof peekbuf) - 1])
  257.         return;        /* Sorry, can't oblige you ... */
  258.     *peekp++ = c;
  259. }
  260.  
  261. int    InputPending = 0;
  262.  
  263. char    *Inputp = 0;
  264.  
  265. #if (defined(IPROCS) && !defined(PIPEPROCS))    /* that is, if ptys */
  266. int
  267. jgetchar()
  268. {
  269.     long        reads;
  270.     register int    tmp,
  271.             nfds;
  272.     int        c;
  273.  
  274.     if (nchars <= 0) {
  275.         /* Get a character from the keyboard, first checking for
  276.            any input from a process.  Handle that first, and then
  277.            deal with the terminal input. */
  278.         do {
  279.             do {
  280.                 reads = global_fd;
  281.                 nfds = select(32, &reads, (long *) 0, (long *) 0, (struct timeval *) 0);
  282.             } while (nfds < 0 && errno == EINTR);
  283.  
  284.             if (nfds == -1)
  285.                 complain("\rerror %d in select %ld", errno, global_fd);
  286.             else {
  287.                 if (reads & 01) {
  288.                     nchars = read(0, smbuf, sizeof(smbuf));
  289.                     reads &= ~01;
  290.                     nfds -= 1;
  291.                 }
  292.                 while (nfds--) {
  293.                     tmp = ffs(reads) - 1;
  294.                     read_proc(tmp);
  295.                     reads &= ~(1L << tmp);
  296.                 }
  297.             }
  298.         } while (nchars <= 0);
  299.  
  300.         if (nchars <= 0)
  301.             finish(SIGHUP);
  302.  
  303.         bp = smbuf;
  304.         InputPending = (nchars > 1);
  305.     }
  306.  
  307.     if (((c = *bp) & 0200) && MetaKey != 0) {
  308.         *bp = (c & CHARMASK);
  309.         return '\033';
  310.     }
  311.     nchars -= 1;
  312.     return *bp++ & 0377;
  313. }
  314.  
  315. #else
  316.  
  317. jgetchar()
  318. {
  319.     register int    c;
  320.     struct header {
  321.         int    pid;
  322.         int    nbytes;
  323.     } header;
  324.     int    n;
  325.  
  326. normal:
  327.     if (nchars <= 0) {
  328.         bp = smbuf;
  329. #ifdef MSDOS
  330.         *bp = getrawinchar();
  331.         nchars = 1;
  332. #else
  333. # ifdef IPROCS
  334.         if (NumProcs == 0) {
  335. # endif
  336.             do
  337.                 nchars = read(0, smbuf, sizeof smbuf);
  338. # ifdef SYSV
  339.             while (nchars == 0 || (nchars < 0 && errno == EINTR));
  340.             if (nchars < 0)
  341. # else
  342.             while (nchars < 0 && errno == EINTR);
  343.             if (nchars <= 0)
  344. # endif /* SYSV */
  345.                 finish(SIGHUP);
  346. # ifdef IPROCS
  347.         } else for (;;) {
  348.             n = f_readn(ProcInput, &header, sizeof (header));
  349.             if (n == EOF) {
  350.                 printf("\rError reading kbd process.\n");
  351.                 finish(1);
  352.             }
  353.             /* data is from the keyboard process */
  354.             if (header.pid == kbd_pid) {
  355.                 nchars = f_readn(ProcInput, smbuf, header.nbytes);
  356.                 if (nchars != header.nbytes) {
  357.                     printf("\rError reading kbd process.");
  358.                     finish(1);
  359.                 } else
  360.                     break;
  361.             } else
  362.                 read_proc(header.pid, header.nbytes);
  363.             if (NumProcs == 0) {
  364.                 (void) kbd_stop();
  365.                 goto normal;
  366.             }
  367.         }
  368. # endif /* IPROCS */
  369. #endif /* MSDOS */
  370.         InputPending = nchars > 0;
  371.     }
  372.     if (((c = *bp) & 0200) && MetaKey != 0) {
  373.         *bp = (c & CHARMASK);
  374.         return '\033';
  375.     }
  376.     nchars -= 1;
  377.     return (*bp++ & CHARMASK);
  378. }
  379.  
  380. #endif /* IPROCS */
  381.  
  382. /* Returns non-zero if a character waiting */
  383.  
  384. int
  385. charp()
  386. {
  387.     int    some = 0;
  388.  
  389.     if (InJoverc != 0 || nchars > 0 || Inputp != 0)
  390.         return 1;
  391. #ifdef BRLUNIX
  392.     {
  393.         static struct sg_brl gttyBuf;
  394.  
  395.         gtty(0, (char *) >tyBuf);
  396.         if (gttyBuf.sg_xflags & INWAIT)
  397.             some += 1;
  398.     }
  399. #endif
  400. #ifdef FIONREAD
  401.     {
  402.         long c;
  403.  
  404.         if (ioctl(0, FIONREAD, (UnivPtr) &c) == -1)
  405.             c = 0;
  406.         some = (c > 0);
  407.     }
  408. #endif /* FIONREAD */
  409. #if defined(SYSV) || defined(M_XENIX)
  410.     setblock(0, 0);        /* turn blocking off */
  411.     nchars = read(0, smbuf, sizeof smbuf);    /* Is anything there? */
  412.     setblock(0, 1);        /* turn blocking on */
  413.     if (nchars > 0)        /* something was there */
  414.         bp = smbuf;        /* make sure bp points to it */
  415.     some = (nchars > 0);    /* just say we found something */
  416. #endif /* SYSV */
  417. #ifdef c70
  418.     some = !empty(0);
  419. #endif
  420. #ifdef MSDOS
  421.     some = rawkey_ready();
  422. #endif
  423. #ifdef MAC
  424.     some = rawchkc();
  425. #endif
  426.     return some;
  427. }
  428.  
  429. void    do_sgtty proto((void));
  430. #ifdef BIFF
  431. private void    biff_init proto((void));
  432. #endif
  433.  
  434. #ifdef TERMCAP
  435.  
  436. private void
  437. ResetTerm()
  438. {
  439.     do_sgtty();        /* this is so if you change baudrate or stuff
  440.                    like that, JOVE will notice. */
  441.     ttyset(ON);
  442.     putpad(TI, 1);
  443.     putpad(VS, 1);
  444.     putpad(KS, 1);
  445. #ifdef UNIX
  446.     (void) chkmail(YES);    /* force it to check to we can be accurate */
  447. #endif
  448. #ifdef BIFF
  449.     if (BiffChk != dw_biff)
  450.         biff_init();
  451.     /* just in case we changed our minds about whether to deal with
  452.        biff */
  453. #endif
  454. }
  455.  
  456. private void
  457. UnsetTerm(mesg)
  458. char    *mesg;
  459. {
  460.     ttyset(OFF);
  461. #ifdef ID_CHAR
  462.     INSmode(0);
  463. #endif
  464.     putpad(KE, 1);
  465.     putpad(VE, 1);
  466.     /* 
  467.      *  For terminals without an alternate page, go the bottom of the
  468.      *  screen. Alternate page - just return to the original place on
  469.      *  the screen
  470.      */
  471.     if (!TE) {
  472.         Placur(ILI, 0);
  473.         putpad(CE, 1);
  474.     } else {
  475.         putpad(TE, 1);
  476.     }
  477.     if (mesg[0] != '\0')
  478.         writef("%s\n", mesg);
  479.     flusho();
  480. }
  481. #endif /* TERMCAP */
  482.  
  483. #ifdef JOB_CONTROL
  484. void
  485. PauseJove()
  486. {
  487.     UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
  488.     (void) kill(0, SIGTSTP);
  489.     ResetTerm();
  490.     ClAndRedraw();
  491. }
  492. #endif
  493.  
  494.  
  495. #ifndef MAC
  496. void
  497. Push()
  498. {
  499. #ifndef MSDOS
  500.     int    pid;
  501.     SIGRESULT    (*old_quit) proto((int)) = signal(SIGQUIT, SIG_IGN);
  502. #endif /* MSDOS */
  503.     SIGRESULT    (*old_int) proto((int)) = signal(SIGINT, SIG_IGN);
  504.  
  505. #ifndef MSDOS
  506. #ifdef IPROCS
  507.     SigHold(SIGCHLD);
  508. #endif
  509. #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
  510.     SigHold(SIGWINCH);
  511. #endif
  512.     alarm(0);
  513.     switch (pid = fork()) {
  514.     case -1:
  515.         complain("[Fork failed]");
  516.         /*NOTREACHED*/
  517.  
  518.     case 0:
  519.         UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
  520. #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
  521.         SigRelse(SIGWINCH);
  522. #endif
  523. #ifdef IPROCS
  524.         SigRelse(SIGCHLD);
  525. #endif
  526.         (void) signal(SIGTERM, SIG_DFL);
  527. #else /* MSDOS */
  528.     UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
  529. #endif /* MSDOS */
  530.         (void) signal(SIGINT, SIG_DFL);
  531. #ifdef UNIX
  532.         (void) signal(SIGQUIT, SIG_DFL);
  533.         execl(Shell, basename(Shell), "-i", (char *)0);
  534.         message("[Execl failed]");
  535.         _exit(1);
  536.     }
  537. #ifdef IPROCS
  538.     SigRelse(SIGCHLD);
  539. #endif
  540.     dowait(pid, (int *) 0);
  541. #endif /* UNIX */
  542. #ifdef MSDOS
  543.     break_rst();
  544.     if (spawnl(0, Shell, basename(Shell), (char *)0) == -1)
  545.         message("[Spawn failed]");
  546. #endif /* MSDOS */
  547. #ifndef MAC
  548.     ResetTerm();
  549. #endif
  550. #if defined(TIOCGWINSZ) && defined(SIGWINCH) && defined(SigRelse)
  551.     SigRelse(SIGWINCH);
  552. #endif
  553.     ClAndRedraw();
  554. #ifndef MSDOS
  555.     (void) signal(SIGQUIT, old_quit);
  556. #else /* MSDOS */
  557.     break_off();
  558.     getCWD();
  559. #endif /* MSDOS */
  560.     (void) signal(SIGINT, old_int);
  561. #ifndef MSDOS
  562.     (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
  563. #endif
  564. }
  565. #endif /* MAC */
  566.  
  567. int    OKXonXoff = 0,        /* ^S and ^Q initially DON'T work */
  568.     IntChar = CTL(']');
  569.  
  570. private void
  571. ttsize()
  572. {
  573. #ifdef UNIX
  574. #   ifdef TIOCGWINSZ
  575.     struct winsize win;
  576.  
  577.     if (ioctl (0, TIOCGWINSZ, (UnivPtr) &win) == 0) {
  578.         if (win.ws_col)
  579.             CO = win.ws_col;
  580.         if (win.ws_row)
  581.             LI = win.ws_row;
  582.     }
  583. #   else /* TIOCGWINSZ */
  584. #    ifdef BTL_BLIT
  585. #include <sys/jioctl.h>
  586.     struct jwinsize jwin;
  587.  
  588.     if (ioctl(0, JWINSIZE, &jwin) == 0) {
  589.         if (jwin.bytesx)
  590.             CO = jwin.bytesx;
  591.         if (jwin.bytesy)
  592.             LI = jwin.bytesy;
  593.     }
  594. #    endif /* BTL_BLIT */
  595. #   endif /* TIOCGWINSZ */
  596. #endif /* UNIX */
  597. #ifdef MAC
  598.     CO = getCO();    /* see mac.c */
  599.     LI = getLI();
  600.     Windchange = 1;
  601.     clr_page();
  602. #endif
  603.     ILI = LI - 1;
  604. }
  605.  
  606. #ifdef BIFF
  607. private void
  608. biff_init()
  609. {
  610.     dw_biff = ((BiffChk) &&
  611. #   ifndef BSD4_2
  612.            ((tt_name != 0) || (tt_name = ttyname(0))) &&
  613.            (stat(tt_name, &tt_stat) != -1) &&
  614. #   else
  615.            (fstat(0, &tt_stat) != -1) &&
  616. #   endif
  617.            (tt_stat.st_mode & S_IEXEC));    /* he's using biff */
  618.  
  619. }
  620.  
  621. private void
  622. biff(on)
  623. int    on;
  624. {
  625.     if (dw_biff == NO)
  626.         return;
  627. #   ifndef BSD4_2
  628.     (void) chmod(tt_name, on ? tt_stat.st_mode :
  629.                    (tt_stat.st_mode & ~S_IEXEC));
  630. #   else
  631.     (void) fchmod(0, on ? tt_stat.st_mode :
  632.                   (tt_stat.st_mode & ~S_IEXEC));
  633. #   endif
  634. }
  635.  
  636. #endif /* BIFF */
  637.  
  638. private void
  639. ttinit()
  640. {
  641. #ifdef BIFF
  642.     biff_init();
  643. #endif
  644. #ifdef TIOCSLTC
  645.     (void) ioctl(0, TIOCGLTC, (UnivPtr) &ls[OFF]);
  646.     ls[ON] = ls[OFF];
  647.     ls[ON].t_suspc = (char) -1;
  648.     ls[ON].t_dsuspc = (char) -1;
  649.     ls[ON].t_flushc = (char) -1;
  650.     ls[ON].t_lnextc = (char) -1;
  651. #endif
  652.  
  653. #if defined(TIOCGETC) && !defined(SYSV)
  654.     /* Change interupt and quit. */
  655.     (void) ioctl(0, TIOCGETC, (UnivPtr) &tc[OFF]);
  656.     tc[ON] = tc[OFF];
  657.     tc[ON].t_intrc = IntChar;
  658.     tc[ON].t_quitc = (char) -1;
  659.     if (OKXonXoff) {
  660.         tc[ON].t_stopc = (char) -1;
  661.         tc[ON].t_startc = (char) -1;
  662.     }
  663. #endif /* TIOCGETC */
  664.     do_sgtty();
  665. }
  666.  
  667. private int    done_ttinit = 0;
  668.  
  669. void
  670. do_sgtty()
  671. {
  672. #ifdef UNIX
  673. # ifdef SYSV
  674.     (void) ioctl(0, TCGETA, (char *) &sg[OFF]);
  675. # else
  676.     (void) gtty(0, &sg[OFF]);
  677. # endif /* SYSV */
  678.     sg[ON] = sg[OFF];
  679.  
  680. # ifdef LPASS8
  681.     (void) ioctl(0, TIOCLGET, (UnivPtr) &lmword[OFF]);
  682.     lmword[ON] = lmword[OFF];
  683.     if (MetaKey == YES)
  684.         lmword[ON] |= LPASS8;
  685.     if (HZ)
  686.         lmword[ON] &= ~LTILDE;
  687. # endif
  688.  
  689. # ifdef SYSV
  690.     TABS = !((sg[OFF].c_oflag & TAB3) == TAB3);
  691.     ospeed = sg[OFF].c_cflag & CBAUD;
  692.  
  693.     if (OKXonXoff)
  694.         sg[ON].c_iflag &= ~(IXON | IXOFF);
  695.     sg[ON].c_iflag &= ~(INLCR|ICRNL|IGNCR);
  696.     sg[ON].c_lflag &= ~(ICANON|ECHO);
  697.     sg[ON].c_oflag &= ~(OCRNL|ONLCR);
  698.     sg[ON].c_cc[VINTR] = IntChar;
  699.     sg[ON].c_cc[VQUIT] = (char) -1;
  700.     sg[ON].c_cc[VMIN] = sizeof smbuf;
  701.     sg[ON].c_cc[VTIME] = 1;
  702. # else
  703.     TABS = !(sg[OFF].sg_flags & XTABS);
  704.     sg[ON].sg_flags &= ~XTABS;
  705.     ospeed = sg[OFF].sg_ospeed;
  706. #  ifdef BRLUNIX
  707.     sg[ON].sg_flags &= ~(ECHO | CRMOD);
  708.     sg[ON].sg_flags |= CBREAK;
  709.  
  710.     /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
  711.     sg[ON].sg_xflags &= ~((sg[ON].sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
  712. #  else
  713.     sg[ON].sg_flags &= ~(ECHO | CRMOD);
  714. #  endif /* BRLUNIX */
  715.  
  716. #  ifdef LPASS8
  717.     sg[ON].sg_flags |= CBREAK;
  718. #  else
  719.     sg[ON].sg_flags |= (MetaKey ? RAW : CBREAK);
  720. #  endif
  721. # endif /* SYSV */
  722. #endif /* UNIX */
  723.  
  724. #ifdef MSDOS
  725. # ifndef IBMPC
  726.     setmode(1, 0x8000);
  727. # endif /* IBMPC */
  728.     TABS = 0;
  729. #endif /* MSDOS */
  730. }
  731.  
  732. void
  733. tty_reset()
  734. {
  735.     if (!done_ttinit)
  736.         return;
  737.     ttyset(OFF);    /* go back to original modes */
  738.     ttinit();
  739.     ttyset(ON);
  740. }
  741.  
  742. /* If n is OFF reset to original modes */
  743.  
  744. void
  745. ttyset(n)
  746. int    n;
  747. {
  748.     if (!done_ttinit && n == 0)    /* Try to reset before we've set! */
  749.         return;
  750. #ifdef UNIX
  751. # ifdef SYSV
  752.     (void) ioctl(0, TCSETAW, (UnivPtr) &sg[n]);
  753. # else
  754. #  ifdef BRLUNIX
  755.     (void) stty(0, &sg[n]);
  756. #  else
  757.     (void) ioctl(0, TIOCSETN, (UnivPtr) &sg[n]);
  758. #  endif /* BRLUNIX */
  759. # endif /* SYSV */
  760.  
  761. # if defined(TIOCSETC) && !defined(SYSV)
  762.     (void) ioctl(0, TIOCSETC, (UnivPtr) &tc[n]);
  763. # endif /* TIOCSETC */
  764. # ifdef TIOCSLTC
  765.     (void) ioctl(0, TIOCSLTC, (UnivPtr) &ls[n]);
  766. # endif /* TIOCSLTC */
  767. # ifdef LPASS8
  768.     (void) ioctl(0, TIOCLSET, (UnivPtr) &lmword[n]);
  769. # endif
  770. #endif /* UNIX */
  771.  
  772. #ifdef MSDOS
  773. # ifndef IBMPC
  774.     setmode(1, n == 0 ? 0x4000 : 0x8000);
  775. # endif
  776. #endif /* MSDOS */
  777.     done_ttinit = 1;
  778. #ifdef BIFF
  779.     biff(!n);
  780. #endif
  781. }
  782.  
  783. int    this_cmd,
  784.     last_cmd,
  785.     LastKeyStruck,
  786.     MetaKey = 0;
  787.  
  788. int
  789. getch()
  790. {
  791.     register int    c,
  792.             peekc;
  793.  
  794.     if (Inputp) {
  795.         if ((c = *Inputp++) != '\0')
  796.             return LastKeyStruck = c;
  797.         Inputp = NULL;
  798.     }
  799.  
  800.     if (InJoverc)
  801.         return EOF;    /* somethings wrong if Inputp runs out while
  802.                    we're reading a .joverc file. */
  803.  
  804. #ifndef MSDOS
  805.     if (ModCount >= SyncFreq) {
  806.         ModCount = 0;
  807.         SyncRec();
  808.     }
  809. #endif /* MSDOS */
  810.  
  811.     /* If we're not interactive and we're not executing a macro,
  812.        AND there are no ungetc'd characters, we read from the
  813.        terminal (i.e., getch()).  And characters only get put
  814.        in macros from inside this if. */
  815.     if (((peekc = c = Peekc()) == EOF) &&
  816.         (Interactive || ((c = mac_getc()) == EOF))) {
  817.         /* So messages that aren't error messages don't
  818.            hang around forever. */
  819.         if (!UpdMesg && !Asking && mesgbuf[0] != '\0' && !errormsg)
  820.             message(NullStr);
  821.         redisplay();
  822. #ifdef UNIX
  823.         inIOread = 1;
  824. #endif
  825.         if ((c = jgetchar()) == EOF)
  826.             finish(SIGHUP);
  827. #ifdef UNIX
  828.         inIOread = 0;
  829. #endif
  830.  
  831.         if (!Interactive && InMacDefine)
  832.             mac_putc(c);
  833.     }
  834.     if (peekc == EOF)    /* don't add_stroke peekc's */
  835.         add_stroke(c);
  836.     return LastKeyStruck = c;
  837. }
  838.  
  839. #ifdef UNIX
  840. private void
  841. dorecover()
  842. {
  843.     /* Since recover is a normal cooked mode program, reset the terminal */
  844.     UnsetTerm(NullStr);
  845. #if defined(IPROCS) && defined(PIPEPROCS)
  846.     kbd_kill();        /* kill the keyboard process */
  847. #endif
  848.     execl(Recover, "recover", "-d", TmpFilePath, (char *) NULL);
  849.     writef("%s: execl failed!\n", Recover);
  850.     flusho();
  851.     _exit(-1);
  852.     /* NOTREACHED */
  853. }
  854. #endif /* UNIX */
  855.  
  856. void
  857. ShowVersion()
  858. {
  859.     s_mess("Jonathan's Own Version of Emacs (%s)", version);
  860. }
  861.  
  862. private void
  863. UNIX_cmdline(argc, argv)
  864. int    argc;
  865. char    *argv[];
  866. {
  867.     int    lineno = 0,
  868.         nwinds = 1;
  869.     Buffer    *b;
  870.  
  871.     ShowVersion();
  872.     while (argc > 1) {
  873.         if (argv[1][0] != '-' && argv[1][0] != '+') {
  874.             int    force = (nwinds > 0 || lineno != 0);
  875.  
  876. #ifdef MSDOS
  877.             strlwr(argv[1]);
  878. #endif
  879.             minib_add(argv[1], force);
  880.             b = do_find(nwinds > 0 ? curwind : (Window *) NULL,
  881.                     argv[1], force);
  882.             if (force) {
  883.                 SetABuf(curbuf);
  884.                 SetBuf(b);
  885.                 if (lineno >= 0)
  886.                     SetLine(next_line(curbuf->b_first, lineno));
  887.                 else
  888.                     SetLine(curbuf->b_last);
  889.                 if (nwinds > 1)
  890.                     NextWindow();
  891.                 if (nwinds)
  892.                     nwinds -= 1;
  893.             }
  894.             lineno = 0;
  895.         } else    switch (argv[1][1]) {
  896.             case 'd':
  897.                 argv += 1;
  898.                 argc -= 1;
  899.                 break;
  900.  
  901.             case 'j':    /* Ignore .joverc in HOME */
  902.                 break;
  903. #ifndef MAC
  904.             case 'p':
  905.                 argv += 1;
  906.                 argc -= 1;
  907.                 if (argv[1] != NULL) {
  908.                     SetBuf(do_find(curwind, argv[1], NO));
  909.                     ErrParse();
  910.                     nwinds = 0;
  911.                 }
  912.                 break;
  913. #endif
  914.             case 't':
  915.                 /* check if syntax is -tTag or -t Tag */
  916.                 if (argv[1][2] != '\0') {
  917.                     find_tag(&(argv[1][2]), YES);
  918.                 } else {
  919.                     argv += 1;
  920.                     argc -= 1;
  921.                     if (argv[1] != NULL)
  922.                         find_tag(argv[1], YES);
  923.                 }
  924.                 break;
  925.  
  926.             case 'w':
  927.                 if (argv[1][2] == '\0')
  928.                     nwinds += 1;
  929.                 else {
  930.                     int    n;
  931.  
  932.                     (void) chr_to_int(&argv[1][2], 10, NO, &n);
  933.                     nwinds += -1 + n;
  934.                 }
  935.                 (void) div_wind(curwind, nwinds - 1);
  936.                 break;
  937.  
  938.             case '0':
  939.             case '1':
  940.             case '2':
  941.             case '3':
  942.             case '4':
  943.             case '5':
  944.             case '6':
  945.             case '7':
  946.             case '8':
  947.             case '9':
  948.                 (void) chr_to_int(&argv[1][1], 10, NO, &lineno);
  949.                 lineno -= 1;
  950.                 break;
  951.             case  0:
  952.                 lineno = -1;    /* goto end of file ... */
  953.                 break;        /* just like some people's */
  954.         }                /* favourite editor */
  955.         argv += 1;
  956.         argc -= 1;
  957.     }
  958. }
  959.  
  960. #ifdef    STDARGS
  961.     void
  962. error(char *fmt, ...)
  963. #else
  964.     /*VARARGS1*/ void
  965. error(fmt, va_alist)
  966.     char    *fmt;
  967.     va_dcl
  968. #endif
  969. {
  970.     va_list    ap;
  971.  
  972.     if (fmt) {
  973.         va_init(ap, fmt);
  974.         format(mesgbuf, sizeof mesgbuf, fmt, ap);
  975.         va_end(ap);
  976.         UpdMesg = YES;
  977.     }
  978.     rbell();
  979.     longjmp(mainjmp, ERROR);
  980. }
  981.  
  982. #ifdef    STDARGS
  983.     void
  984. complain(char *fmt, ...)
  985. #else
  986.     /*VARARGS1*/ void
  987. complain(fmt, va_alist)
  988.     char    *fmt;
  989.     va_dcl
  990. #endif
  991. {
  992.     va_list    ap;
  993.  
  994.     if (fmt) {
  995.         va_init(ap, fmt);
  996.         format(mesgbuf, sizeof mesgbuf, fmt, ap);
  997.         va_end(ap);
  998.         UpdMesg = YES;
  999.     }
  1000.     rbell();
  1001.     longjmp(mainjmp, COMPLAIN);
  1002. }
  1003.  
  1004. #ifdef    STDARGS
  1005.     void
  1006. confirm(char *fmt, ...)
  1007. #else
  1008.     /*VARARGS1*/ void
  1009. confirm(fmt, va_alist)
  1010.     char    *fmt;
  1011.     va_dcl
  1012. #endif
  1013. {
  1014.     char    *yorn;
  1015.     va_list    ap;
  1016.  
  1017.     va_init(ap, fmt);
  1018.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  1019.     va_end(ap);
  1020.     yorn = ask((char *) 0, mesgbuf);
  1021.     if (*yorn != 'Y' && *yorn != 'y')
  1022.         longjmp(mainjmp, COMPLAIN);
  1023. }
  1024.  
  1025. int    RecDepth = 0;
  1026.  
  1027. void
  1028. Recur()
  1029. {
  1030.     char    bname[128];
  1031.     Mark    *m;
  1032.  
  1033.     swritef(bname, "%s", curbuf->b_name);
  1034.     m = MakeMark(curline, curchar, M_FLOATER);
  1035.  
  1036.     RecDepth += 1;
  1037.     UpdModLine = YES;
  1038.     DoKeys(NO);    /* NO means not first time */
  1039.     UpdModLine = YES;
  1040.     RecDepth -= 1;
  1041.     SetBuf(do_select(curwind, bname));
  1042.     if (!is_an_arg())
  1043.         ToMark(m);
  1044.     DelMark(m);
  1045. }
  1046.  
  1047. #ifdef MAC
  1048. jmp_buf auxjmp;
  1049. #endif
  1050.  
  1051. private int    iniargc;    /* main sets these for DoKeys() */
  1052. private char    **iniargv;
  1053.  
  1054. private void
  1055. DoKeys(firsttime)
  1056. int    firsttime;
  1057. {
  1058.     int    c;
  1059.     jmp_buf    savejmp;
  1060.  
  1061.     push_env(savejmp);
  1062.  
  1063.     switch (setjmp(mainjmp)) {
  1064.     case 0:
  1065.         if (firsttime)
  1066.             UNIX_cmdline(iniargc, iniargv);
  1067.         break;
  1068.  
  1069.     case QUIT:
  1070.         if (RecDepth == 0) {
  1071.             if (ModMacs()) {
  1072.                 rbell();
  1073.                 if (CharUpcase(*ask("No",
  1074. "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
  1075.                     break;
  1076.             }
  1077.             if (ModBufs(0)) {
  1078.                 rbell();
  1079.                 if (CharUpcase(*ask("No",
  1080. "Some buffers haven't been saved; leave anyway? ")) != 'Y')
  1081.                     break;
  1082.             }
  1083. #ifdef IPROCS
  1084.             KillProcs();
  1085. #endif
  1086.         }
  1087.         pop_env(savejmp);
  1088.         return;
  1089.  
  1090.     case ERROR:
  1091.         getDOT();    /* God knows what state linebuf was in */
  1092.         /*FALLTHROUGH*/
  1093.     case COMPLAIN:
  1094.         {
  1095.         gc_openfiles();        /* close any files we left open */
  1096.         errormsg = YES;
  1097.         unwind_macro_stack();
  1098.         Asking = 0;
  1099.         curwind->w_bufp = curbuf;
  1100.         DisabledRedisplay = NO;
  1101.         redisplay();
  1102.         break;
  1103.         }
  1104.     }
  1105.  
  1106.     this_cmd = last_cmd = 0;
  1107.  
  1108.     for (;;) {
  1109. #ifdef MAC
  1110.         setjmp(auxjmp);
  1111. #endif
  1112.         if (this_cmd != ARG_CMD) {
  1113.             clr_arg_value();
  1114.             last_cmd = this_cmd;
  1115.             init_strokes();
  1116.         }
  1117. #ifdef MAC
  1118.         HiliteMenu(0);
  1119.         EventCmd = 0;
  1120.         menus_on();
  1121. #endif
  1122.         c = getch();
  1123.         if (c == EOF)
  1124.             continue;
  1125.         dispatch(c);
  1126.     }
  1127. }
  1128.  
  1129. int    Crashing = 0;
  1130.  
  1131. private char **
  1132. scanvec(args, str)
  1133. register char    **args,
  1134.         *str;
  1135. {
  1136.     while (*args) {
  1137.         if (strcmp(*args, str) == 0)
  1138.             return args;
  1139.         args += 1;
  1140.     }
  1141.     return 0;
  1142. }
  1143.  
  1144. #ifdef UNIX
  1145. int    UpdFreq = 30,
  1146.     inIOread = 0;
  1147.  
  1148. private SIGRESULT
  1149. updmode(junk)
  1150. int    junk;    /* passed in on signal; of no interest */
  1151. {
  1152.     UpdModLine = YES;
  1153.     if (inIOread)
  1154.         redisplay();
  1155. #ifndef JOB_CONTROL
  1156.     (void) signal(SIGALRM, updmode);
  1157. #endif
  1158.     (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
  1159.     SIGRETURN;
  1160. }
  1161. #endif /* UNIX */
  1162.  
  1163. #ifdef MSDOS
  1164. # ifndef IBMPC
  1165. char    ttbuf[JBUFSIZ];
  1166. # endif    /* IBMPC */
  1167. #endif /* MSDOS */
  1168.  
  1169. #if defined(MAC) || (defined(TIOCGWINSZ) && defined(SIGWINCH))
  1170. #ifndef    MAC
  1171. private
  1172. #endif
  1173. SIGRESULT
  1174. win_reshape(junk)
  1175. int    junk;    /* passed in when invoked by a signal; of no interest */
  1176. {
  1177.     register int    oldLI;
  1178.     register int newsize, total;
  1179.     register Window *wp;
  1180.  
  1181. #ifdef UNIX
  1182.     (void) SigHold(SIGWINCH);
  1183. #endif
  1184.     /*
  1185.      * Save old number of lines.
  1186.      */
  1187.     oldLI = LI;
  1188.  
  1189.     /*
  1190.      * Get new line/col info.
  1191.      */
  1192.     ttsize();
  1193.  
  1194.     /*
  1195.      * LI has changed, and now holds the
  1196.      * new value.
  1197.      */
  1198.     /*
  1199.      *  Go through the window list, changing each window size in
  1200.      *  proportion to the resize. If a window becomes too small,
  1201.      *  delete it. We keep track of all the excess lines (caused by
  1202.      *  roundoff!), and give them to the current window, as a sop -
  1203.      *  can't be more than one or two lines anyway. This seems fairer
  1204.      *  than just resizing the current window.
  1205.      */
  1206.     wp = fwind;
  1207.     total = 0;
  1208.     do {
  1209.         newsize = LI * wp->w_height / oldLI;
  1210.  
  1211.         if (newsize < 2) {
  1212.             total += wp->w_height;
  1213.             wp = wp->w_next;
  1214.             del_wind(wp->w_prev);
  1215.         } else {
  1216.             wp->w_height = newsize;
  1217.             total += newsize;
  1218.             wp = wp->w_next;
  1219.         }
  1220.     } while (wp != fwind);
  1221.  
  1222.     curwind->w_height += LI - total - 1;
  1223.  
  1224.     /* Make a new screen structure */
  1225.     make_scr();
  1226.     /* Do a 'hard' update on the screen - clear and redraw */
  1227.     cl_scr(YES);
  1228.     flusho();
  1229.     redisplay();
  1230.  
  1231. #ifdef UNIX
  1232.     (void) signal(SIGWINCH, win_reshape);
  1233. #endif
  1234.     SIGRETURN;
  1235. }
  1236. #endif
  1237.  
  1238. void
  1239.  
  1240. #ifdef MAC    /* will get args from user, if option key held during launch */
  1241. main()
  1242. {
  1243.     int argc;
  1244.     char **argv;
  1245. #else
  1246. main(argc, argv)
  1247. int    argc;
  1248. char    *argv[];
  1249. {
  1250. #endif /* MAC */
  1251.     char    *cp;
  1252.     char    ttbuf[MAXTTYBUF];
  1253. #ifndef MSDOS
  1254. # ifndef VMUNIX
  1255.     char    s_iobuff[LBSIZE],
  1256.         s_genbuf[LBSIZE],
  1257.         s_linebuf[LBSIZE];
  1258.     /* The way I look at it, there ain't no way I is gonna run
  1259.        out of stack space UNLESS I have some kind of infinite
  1260.        recursive bug.  So why use up some valuable memory, when
  1261.        there is plenty of space on the stack?  (This only matters
  1262.        on wimpy pdp11's, of course.) */
  1263.  
  1264.     iobuff = s_iobuff;
  1265.     genbuf = s_genbuf;
  1266.     linebuf = s_linebuf;
  1267. # endif
  1268.  
  1269. #else /* MSDOS */
  1270.     char    *getenv();
  1271. #endif /* MSDOS */
  1272.  
  1273. #ifdef MAC
  1274.     MacInit();        /* initializes all */
  1275.     if(make_cache() == 0) exit(-1);
  1276.     argc = getArgs(&argv);
  1277. #endif /* MAC */
  1278.  
  1279.     iniargc = argc;
  1280.     iniargv = argv;
  1281.  
  1282.     if (setjmp(mainjmp)) {
  1283.         writef("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
  1284.         finish(6);
  1285.     }
  1286.  
  1287. #ifdef MSDOS
  1288.     /* import the temporary file path from the environment and
  1289.        fix the string, so that we can append a slash safely    */
  1290.  
  1291.     if (((cp = getenv("TMP")) || (cp = getenv("TMPDIR"))) &&
  1292.         (*cp != '\0')) {
  1293.         strcpy(TmpFilePath, cp);
  1294.         cp = &TmpFilePath[strlen(TmpFilePath)-1];
  1295.         if ((*cp == '/') || (*cp == '\\'))
  1296.             *cp = 0;
  1297.     }
  1298.     ShFlags[0] = switchar();
  1299. #endif /* MSDOS */
  1300.  
  1301.     getTERM();    /* Get terminal. */
  1302.     if (getenv("METAKEY"))
  1303.         MetaKey = 1;
  1304.     ttsize();
  1305. #ifdef MAC
  1306.     InitEvents();
  1307. #else
  1308.     InitCM();
  1309. #endif
  1310.  
  1311.     d_cache_init();        /* initialize the disk buffer cache */
  1312. #ifdef MSDOS
  1313.     if ((cp = getenv("COMSPEC")) && (*cp != '\0')) {
  1314.         strcpy(Shell, cp);
  1315.     }
  1316.     if ((cp = getenv("DESCRIBE")) && (*cp != '\0'))
  1317.        strcpy(CmdDb, cp);
  1318. #else /* !MSDOS */
  1319. #ifndef MAC
  1320.     if ((cp = getenv("SHELL"))!=NULL && (*cp != '\0')) {
  1321.         strcpy(Shell, cp);
  1322.     }
  1323. #endif
  1324. #endif /* !MSDOS */
  1325.  
  1326.     make_scr();
  1327.     mac_init();    /* Initialize Macros */
  1328.     winit();    /* Initialize Window */
  1329. #ifdef IPROCS
  1330.     pinit();    /* Pipes/process initialization */
  1331. #endif
  1332.     buf_init();
  1333.  
  1334.     {
  1335.         char    **argp;
  1336.  
  1337.         if ((argp = scanvec(argv, "-d"))!=NULL
  1338. #ifdef UNIX
  1339.             && chkCWD(argp[1])
  1340. #endif
  1341.             )
  1342.             setCWD(argp[1]);
  1343.         else
  1344.             getCWD();    /* After we setup curbuf in case we have to getwd() */
  1345.     }
  1346.  
  1347.     HomeDir = getenv("HOME");
  1348.     if (HomeDir == NULL)
  1349.         HomeDir = "/";
  1350.     HomeLen = strlen(HomeDir);
  1351.  
  1352. #ifdef UNIX
  1353. # ifdef SYSV
  1354.     swritef(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
  1355. # else
  1356.     swritef(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
  1357. # endif
  1358. #endif
  1359.  
  1360.     InitKeymaps();
  1361.  
  1362.     ttinit();    /* initialize terminal (before ~/.joverc) */
  1363.     settout(ttbuf);    /* not until we know baudrate */
  1364. #ifndef MAC
  1365.     ResetTerm();
  1366. #endif
  1367.  
  1368.     (void) joverc(Joverc);            /* system wide .joverc */
  1369.     cp = 0;
  1370. #if defined(MSDOS) || defined(UNIX)
  1371.     /* If a JOVERC environment variable is set, then use that instead */
  1372.     if ((cp = getenv("JOVERC")) && (*cp != '\0'))
  1373.        (void) joverc(cp);
  1374. #endif /* MSDOS || UNIX */
  1375.     if (!scanvec(argv, "-j") && (!cp || *cp == '\0')) {
  1376.         char    tmpbuf[100];
  1377.  
  1378.         swritef(tmpbuf, "%s/.joverc", HomeDir);
  1379.         (void) joverc(tmpbuf);        /* .joverc in home directory */
  1380.     }
  1381.  
  1382. #ifndef MSDOS
  1383.     if (scanvec(argv, "-r"))
  1384.         dorecover();
  1385.     if (scanvec(argv, "-rc"))
  1386.         FullRecover();
  1387. #endif     /* MSDOS */
  1388.  
  1389. #ifdef MSDOS
  1390.     (void) signal(SIGINT, SIG_IGN);
  1391.     break_off();    /* disable ctrl-c checking */
  1392. #endif /* MSDOS */
  1393. #ifdef UNIX
  1394.     (void) signal(SIGHUP, finish);
  1395.     (void) signal(SIGINT, finish);
  1396.     (void) signal(SIGBUS, finish);
  1397.     (void) signal(SIGSEGV, finish);
  1398.     (void) signal(SIGPIPE, finish);
  1399.     (void) signal(SIGTERM, SIG_IGN);
  1400. # if defined(TIOCGWINSZ) && defined(SIGWINCH)
  1401.     (void) signal(SIGWINCH, win_reshape);
  1402. # endif
  1403.     /* set things up to update the modeline every UpdFreq seconds */
  1404.     (void) signal(SIGALRM, updmode);
  1405.     (void) alarm((unsigned) (UpdFreq - (time((time_t *) 0) % UpdFreq)));
  1406. #endif /* UNIX */
  1407.     cl_scr(1);
  1408.     flusho();
  1409.     RedrawDisplay();    /* start the redisplay process. */
  1410.     DoKeys(YES);
  1411.     finish(0);
  1412. }
  1413.  
  1414. #ifdef MSDOS
  1415.  
  1416. #include <dos.h>
  1417.  
  1418. static    char break_state;
  1419.  
  1420. /* set the break state to off */
  1421. private void
  1422. break_off()
  1423. {
  1424.     union REGS regs;
  1425.  
  1426.     regs.h.ah = 0x33;        /* break status */
  1427.     regs.h.al = 0x00;        /* request current state */
  1428.     intdos(®s, ®s);
  1429.     break_state = regs.h.dl;
  1430.     bdos(0x33, 0, 1);    /* turn off break */
  1431. }
  1432.  
  1433. /* reset the break state */
  1434. private void
  1435. break_rst()
  1436. {
  1437.     bdos(0x33, break_state, 1);
  1438. }
  1439. #endif
  1440.